/**
 * 
 */

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import bean.UserBean;

import com.e885.log.E885Logger;

/**
 * 一個認證的 Filter, 最主要是使用者沒有登入時, 就會返回登入頁, 目前只有針對 url 是 /secure/* 才做 Filter
 * @author Eric.Kao(gau168.gau@msa.hinet.net)
 * @version 1.0
 * @company E885 Group
 * @copyright Copyright (c) 2001-2008
 */

public class AuthenticationFilter implements Filter
{
	private String loginPage;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy()
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException
	{
		if( request instanceof HttpServletRequest && response instanceof HttpServletResponse )
		{
			HttpServletRequest httpServletRequest = (HttpServletRequest)request;
			HttpServletResponse httpServletResponse = (HttpServletResponse)response;
			
			HttpSession session = httpServletRequest.getSession( true );
			
			UserBean bean = (UserBean)session.getAttribute( "UserBean" );
			if( bean == null )
			{
				E885Logger.testLog.debug( "使用 Filter 檢查是否登入:未登入" );
				
				
				//目前設定的 loginPage	是  "/login/login.jsp",因為有加 "/" 表示從最基本的根開始算起, 針對以下二種狀況分別討論
				//1. request.getRequestDispatcher( loginPage ).forward(): url 將為 http://127.0.0.1:8080/AuthenticationFilter/login/login.jsp
				//2. response.sendRedirect( loginPage ): url 將為 http://127.0.0.1:8080/login/login.jsp
				//所以可以看出, 一個有 context path, 一個沒有
				String contentPath = httpServletRequest.getContextPath();
				
				//這邊使用 encodeRedirectURL(), 不使用 encodeURL(), 經 API 的解釋, 是 encodeRedirectURL() 是用在 sendRedirect()
				String redirect = httpServletResponse.encodeRedirectURL( contentPath +  loginPage );
				
				//這邊為何要使用 redirect, 因為要把整個路徑導到,ex: http://127.0.0.1:8080/AuthenticationFilter/login/login.jsp.
				//使用 request.getRequestDispatcher().forward() 會有下列問題
				//假設目前路徑為 http://127.0.0.1:8080/AuthenticationFilter/secure/userInfo, 那麼這時如果使 request.getRequestDispatcher().forward()
				//那麼在使用 login.jsp 將會有路徑上的錯誤
				httpServletResponse.sendRedirect( redirect );
			}
			else
			{
    			E885Logger.testLog.debug( "使用 Filter 檢用是否登入:已登入" );
    			
    			chain.doFilter( request, response );
			}
		}
		else
			throw new ServletException( "Only support protocol:http and https" );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init( FilterConfig config ) throws ServletException
	{
		loginPage = config.getInitParameter( "loginPage" );
		
		E885Logger.testLog.debug( "loginPage:" + loginPage );

		if( loginPage == null || loginPage.trim().length() == 0 )
			throw new ServletException( "loginPage is null" );
	}

}
